'''
Created on Dec 4, 2009

@author: tliu
'''
from google.appengine.ext import db
from error import UserError
from Subscription import Subscription
from error import TagError

def getUserByUsername(username):
    current_users = User.all()
    matching_users = filter(lambda x:x.username == username, current_users)
    if len(matching_users) < 1:
        raise UserError.UserError("No such user!")
    
    return matching_users[0]
    
'''
    method for checking duplicate email
'''    
def getUserByEmail(email):
    current_users = User.all()
    matching_users = filter(lambda x:x.email == email, current_users)
    if len(matching_users) < 1:
        return False
    
    return True

def createUser(username, password, email, currency, name, city, link, desc, gender, age):
    # Check for duplicate usernames and error if we find one.
    if User.get_by_key_name(username) != None:
        raise UserError("Duplicate username!")
    
    user = User(username=username,
             password=password,
             email=email,
             currency=currency,
             name=name,
             city=city,
             link=link,
             desc=desc,
             gender=gender,
             age=age,
             key_name=username)
    user.tag_list = []
    user.projects = []
    user.blog_entries = []
    user.taggings = []
    user.auctions = []
    user.feed_items = []
    user.put()
    
    return user
    
class User(Subscription):
    username = db.StringProperty(required=True)
    password = db.StringProperty(required=True)
    email = db.EmailProperty(required=True)
    currency = db.FloatProperty(required=True)
    name = db.StringProperty(required=True)
    city = db.StringProperty(required=True)
    age = db.IntegerProperty(required=True)
    link = db.LinkProperty(required=False)
    desc = db.TextProperty(required=True)
    gender = db.StringProperty(required=True, choices=set(["Female", "Male"]))
    taggings = db.ListProperty(db.Key, required=True)
    blog_entries = db.ListProperty(db.Key, required=True) 
    projects = db.ListProperty(db.Key, required=True) 
    auctions = db.ListProperty(db.Key, required=True) 
    feed_items = db.ListProperty(db.Key, required=True)
    tag_list = db.StringListProperty()
       
    def _updateCurrency(self, delta):    
        self.currency += delta
        self.put()
        
    def addTag(self, tag):
        if tag in self.tag_list:
            raise TagError.TagError("Tag already exists!")
        self.tag_list.append(tag) 
        self.put()   
        
    def removeTag(self, tag):
        if tag not in self.tag_list:
            raise TagError.TagError("Tag does not exist!")
        self.tag_list.remove(tag)
        self.put()    
        
    def addTagging(self, otherUser, tags):
        from Tagging import createTagging
        tagging = createTagging(otherUser.key(), tags)
        self.taggings.append(tagging.key())
        self.put()
        
    def getTaggings(self):
        from Tagging import Tagging
        return map(lambda x:Tagging.get(x), self.taggings)

    def updatePassword(self, password):
        self.password = password
        self.put()
        
    def updateEmail(self, email):
        self.email = email
        self.put()
        
    def updateName(self, name):
        self.name = name
        self.put()
        
    def updateCity(self, city):
        self.city = city
        self.put()
    
    def updateLink(self, link):
        self.link = link
        self.put()
        
    def updateDesc(self, desc):
        self.desc = desc
        self.put()
         
    def updateAge(self, age):
        self.age = age
        self.put()
        
    def updateGender(self, gender):
        self.gender = gender
        self.put()        
         
    def subtractCurrency(self, amount):
        if amount < 0:
            raise ValueError("Can't subtract a negative amount!")
        if self.currency - amount < 0:
            raise UserError("Not enough money!")
        else:
            self._updateCurrency(-1 * amount)
            
    def addCurrency(self, amount):
        if amount < 0:
            raise ValueError("Can't add a negative amount!")
        self._updateCurrency(amount)
    
    def addBlogEntry(self, entry):
        self.blog_entries.append( entry.key())
        self.put()
    
    def getBlogEntries(self):
        from Entry import Entry
        return map(lambda x:Entry.get(x), self.blog_entries)
    
    def addProject(self, project):
        self.projects.append(project.key())
        self.put()
    
    def getProjects(self):
        from Project import Project
        return map(lambda x:Project.get(x), self.projects)
    
    
    def addFeedItem(self, feed_item):
        self.feed_items.append(feed_item.key())
        self.put()
    
    def getFeedItems(self):
        return map(lambda x:Subscription.get(x), self.feed_items)

    
    def addAuction(self, auction):
        self.auctions.append(auction.key())
        self.put()
    
    def getAuctions(self):
        from Auction import Auction
        return map(lambda x:Auction.get(x), self.auctions)
    
    def getItems(self):
        item_list = []
        for entry in self.getBlogEntries():
            item_list.append({"title" : "%s: %s" % (self.project_ref.name, entry.title),
                              "date" : entry.date,
                              "content" : entry.content,
                              "author" : entry.author.name,
                              "url" : "/profile?user=%s" % self.username,
                              "footer" : "Comments: %d" % len(entry.comments)}) 
        return item_list
    